﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed

#pragma once

#include "IOffsetCoedgeMap.h"
#include "GcmpGeometryInterface.h"
#include "GbmpConstants.h"

namespace gcmp
{
    class IPolygon;
    class IPolyCurve;
    class ISurface;
    class ICurve2d;

    /// \brief 几何偏移类，用于实现几何对象的偏移操作
    ///
    class GCMP_GEOMETRY_INTERFACE_EXPORT AlgorithmOffset
    {
    public:
        /// \brief  对Polygon做offset偏移多边形
        ///
        /// \param pOriginalPolygon          原始多边形
        /// \param dOffsetDistance           偏移距离(为正值时，在右手坐标系下，沿polygon法向正向向下看，外环向左侧偏置，内环向外侧偏置；负值反之)
        /// \param connectType               相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param dEpsilon                  偏移过程中判断是否共点的容差
        /// \param opOffsetPolygon           偏移后的Polygon
        /// \return 偏移前后，边的对应关系
        static OwnerPtr<IOffsetCoedgeMap> Offset(const IPolygon* pOriginalPolygon, OwnerPtr<IPolygon> &opOffsetPolygon, double dOffsetDistance, OffsetConnect connectType, double dEpsilon = Constants::DISTANCE_ITERATION_EPS);
        
        /// \brief  对Polygon做offset
        /// \param pInitPolygon          初始多边形
        /// \param OffsetDis    Offset的距离数组，对于初始多边形的每条边，可以用不同距离做Offset，顺序填充这个距离数组即可
        ///                                              (为正值时，在右手坐标系下，沿polygon法向正向向下看，外环向左侧偏置，内环向外侧偏置；负值反之)
        /// \param OffsetConnectOption connectMode   相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param dEpsilon                   偏移过程中判断是否共点的容差，通常给: DISTANCE_ITERATION_EPS = 1E-4
        /// \param &opOffsetPolygon 偏移后的Polygon
        /// \return OffsetCoedgeMap 偏移前后，边的对应关系
        static  OwnerPtr<IOffsetCoedgeMap> Offset(const IPolygon* pOriginalPolygon, OwnerPtr<IPolygon> &opOffsetPolygon, const std::vector<double>& offsetDistance, OffsetConnect connectType, double dEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief  偏移多段线， 不处理自交
        ///
        /// \param pOriginalPolyCurve         初始多段线
        /// \param dOffsetDistance            偏移距离(为正值时，在右手坐标系下，沿多段线法向正向向下看，沿着多段线中曲线的箭头方向，向左侧偏置；负值反之)
        /// \param connectType                相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param dEpsilon                   偏移过程中判断是否共点的容差
        /// \param opOffsetPolyCurve          偏移后多段线
        /// \return 偏移前后，边的对应关系
        static OwnerPtr<IOffsetCoedgeMap> Offset(const IPolyCurve* pOriginalPolyCurve, OwnerPtr<IPolyCurve> &opOffsetPolyCurve, double dOffsetDistance, OffsetConnect connectType, double dEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief  偏移多段线， 不处理自交, 新算法接口返回结果为多段线列表
        ///
        /// \param pOriginalPolyCurve         初始多段线
        /// \param dOffsetDistance            偏移距离(为正值时，在右手坐标系下，沿多段线法向正向向下看，沿着多段线中曲线的箭头方向，向左侧偏置；负值反之)
        /// \param connectType                相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param dEpsilon                   偏移过程中判断是否共点的容差
        /// \param opOffsetPolyCurve          偏移后多段线集合列表
        /// \return 偏移前后，边的对应关系
        static OwnerPtr<IOffsetCoedgeMap> Offset(const IPolyCurve* pOriginalPolyCurve, std::vector<OwnerPtr<IPolyCurve>> &opOffsetPolyCurve, double dOffsetDistance, OffsetConnect connectType, double dEpsilon = Constants::DISTANCE_ITERATION_EPS);

        /// \brief  偏移多段线， 不处理自交
        ///
        /// \param pOriginalPolyCurve         初始多段线
        /// \param opOffsetPolyCurve          偏移后多段线
        /// \param offsetDistance             Offset的距离数组，对于初始多段线的每条边，可以用不同距离做Offset，顺序填充这个距离数组即可
        ///                                              (为正值时，在右手坐标系下，沿polygon法向正向向下看，外环向左侧偏置，内环向外侧偏置；负值反之)
        /// \param connectType                相邻边之间的连接方式，是延长求交还是用圆弧过渡
        /// \param dEpsilon                   偏移过程中判断是否共点的容差

        /// \return 偏移前后，边的对应关系
        /// \note 1）offsetDistance数目与pOriginalPolyCurve线段不相等，可以处理的，如果offsetDistance数目少于pOriginalPolyCurve线段数目，缺少的偏移距离默认为0；如果offsetDistance数目多于pOriginalPolyCurve线段数目，多余的距离会被忽略；
        ///       2）对于connectType = ArcConnect时，仅向外偏移(负值)并且偏移距离相等时，ArcConnect才真正起作用，否则以ExtendConnect方式执行
        static OwnerPtr<IOffsetCoedgeMap> Offset(const IPolyCurve* pOriginalPolyCurve, OwnerPtr<IPolyCurve> &opOffsetPolyCurve, const std::vector<double>& offsetDistance, OffsetConnect connectType, double dEpsilon = Constants::DISTANCE_ITERATION_EPS);

        
        /// \brief  偏移曲面， 不处理自交
        ///
        /// \param pSurface         初始曲面
        /// \param offsetDistance   偏移距离(为正值时，沿法向正向偏移；负值反之)
        /// \return 偏移后的曲面
        static OwnerPtr<ISurface> Offset(const ISurface *pSurface, double offsetDistance);

        
        /// \brief  偏移二维曲线， 处理自交
        ///
        /// \param pCurve2d         初始二维线
        /// \param offsetDistance   偏移距离(为正值时，在右手坐标系下，沿法向正向向下看，沿着曲线的箭头方向，向左侧偏置；负值反之)
        /// \return 偏移后的二维线
        static OwnerPtr<ICurve2d> Offset(const ICurve2d *pCurve2d, double offsetDistance);

    };
}
